#include "proto.h"
#include <sys/wait.h>

int main (void)
{
	int tcp_fd;
	struct sockaddr_in myaddr;
	struct sockaddr_in client_addr;
	socklen_t client_addr_len;
	int new_fd;
	pid_t pid;
	struct sigaction act;

	//SIGCHLD 当子进程终止的时候, 不变成僵尸进程, 直接释放资源
	act.sa_handler = SIG_DFL;
	act.sa_flags = SA_NOCLDWAIT;
	sigaction (SIGCHLD, &act, NULL);

	tcp_fd = socket (AF_INET, SOCK_STREAM, 0);
	if (-1 == tcp_fd) {
		perror ("socket()");
		exit (1);
	}
	
	//复用地址：解决当服务器终止之后, 但是端口没有被释放,再次bind报错
	int val = 1;
	if (-1 == setsockopt (tcp_fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof (val))) {
		perror ("setsockopt()");
		goto ERROR;
	}

	myaddr.sin_family = AF_INET;
	//网络字节序
	myaddr.sin_port = htons(atoi(SERVER_PORT));
	myaddr.sin_addr.s_addr = INADDR_ANY;
	if (-1 == bind (tcp_fd, (struct sockaddr *)&myaddr, sizeof(myaddr)))
	{
		perror ("bind()");
		goto ERROR;
	}
	//设置监听
	if (-1 == listen (tcp_fd, 32)){
		perror ("listen()");
		goto ERROR;
	}

	client_addr_len = sizeof (struct sockaddr_in);

	while (1) {
		new_fd = accept (tcp_fd, (struct sockaddr *)&client_addr, &client_addr_len);
		if (-1 == new_fd) {
			perror ("accept()");
			goto ERROR;
		}
		printf ("***********************\n");
		printf ("connect successfully whit ip: %s, port:%d\n", \
				inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
		printf ("***********************\n");
		
		if ((pid = fork()) == -1) {
			perror ("fork()");
			goto ERROR;
		}
		if (0 == pid) {
			//数据交换
			close (tcp_fd);
			write (new_fd, "hello", 6);
			close (new_fd);
			exit (0);
		}
		//wait (NULL);
		close (new_fd);
	}
	close (tcp_fd);
	return 0;
ERROR:
	close (tcp_fd);
	exit (1);
}
